#include "EditorWidget.h"

#include <QTextBlock>
//#include <QAbstractTextDocumentLayout>
#include <QScrollBar>
#include <QApplication>
#include <QInputContext>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QDebug>

EditorWidget::EditorWidget(QWidget *parent)
    : QTextEdit(parent)
    , m_inMouseMove(false)
    , m_fontPointSize(18.0)
{
    setLineWrapMode(QTextEdit::NoWrap);
    setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable);
    setUndoRedoEnabled(true);
    setAcceptRichText(false);
    setAcceptDrops(false);

    QSizeF hs = horizontalScrollBar()->size();
    QSizeF vs = verticalScrollBar()->size();
    horizontalScrollBar()->setBaseSize(hs.width(), hs.height() * 2.5);
    verticalScrollBar()->setBaseSize(vs.width() * 2.5, vs.height());

    QTextDocument *doc = new QTextDocument(this);

    //QTextOption option = doc->defaultTextOption();
    //option.setUseDesignMetrics(true);
    //doc->setDefaultTextOption(option);

    QFont font("dejavu sans mono");
    //QFont font("Courier");
    //QFont font("Monospace");
    font.setPointSizeF(m_fontPointSize);
    //font.setFixedPitch(true);
    //font.setStyleHint(QFont::TypeWriter);
    font.setStyleHint(QFont::Monospace);
    //font.setStyleHint(QFont::Courier);
    doc->setDefaultFont(font);

    setDocument(doc);
}

EditorWidget::~EditorWidget()
{
}

void EditorWidget::setFontScale(qreal factor)
{
    QFont f = font();
    qreal value = qBound<qreal>(6.0, m_fontPointSize * factor, 80.0);
    if (qFuzzyCompare(value, f.pointSizeF()))
        return;
    f.setPointSizeF(value);
    setFont(f);
    //update();
    repaint();
}

QMimeData* EditorWidget::createMimeDataFromSelection() const
{
    if (m_inMouseMove)
        return 0;
    return QTextEdit::createMimeDataFromSelection();
}

bool EditorWidget::canInsertFromMimeData(const QMimeData *source) const
{
    if (m_inMouseMove)
        return false;
    return QTextEdit::canInsertFromMimeData(source);
}

void EditorWidget::insertFromMimeData(const QMimeData *source)
{
    if (!m_inMouseMove)
        QTextEdit::insertFromMimeData(source);
}

void EditorWidget::dragEnterEvent(QDragEnterEvent *e)
{
    e->ignore();
}

void EditorWidget::dragLeaveEvent(QDragLeaveEvent *e)
{
    e->ignore();
}

void EditorWidget::dragMoveEvent(QDragMoveEvent *e)
{
    e->ignore();
}

void EditorWidget::dropEvent(QDropEvent *e)
{
    e->ignore();
}

void EditorWidget::mouseMoveEvent(QMouseEvent *e)
{
    // This works around the problem that QTextLine does not allow to call
    // QTextControl::setDragEnabled(false) like e.g. QTextLine does what
    // makes it impossible to just disable drag and drop. So, what we do
    // is to set a helper-boolean so calls to our mimeData-functions can
    // return different states when executed during mouseMove (drag and
    // drop / mloving of selected text what we don't want) or in other
    // scenarious (like on cut/copy/paste what we like to have).
    m_inMouseMove = true;
    QTextEdit::mouseMoveEvent(e);
    m_inMouseMove = false;
}
